package com.wx.references;

import lombok.extern.slf4j.Slf4j;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 虚引用
 * @description:
 * @author: wangxun
 * @createDate: 2021/12/31
 * @version: 1.0
 *
 * Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
 * 	at com.wx.references.PhantomReferences.lambda$main$0(PhantomReferences.java:27)
 * 	at com.wx.references.PhantomReferences$$Lambda$1/517380410.run(Unknown Source)
 * 	at java.lang.Thread.run(Thread.java:748)
 * [INFO ] 2021-12-31 16:16:36,133(0) --> [Finalizer] com.wx.references.Worker.finalize(Worker.java:29): 该休息了
 * 虚引用被回收了：java.lang.ref.PhantomReference@37891589
 */
@Slf4j
public class PhantomReferences {
    public static void main(String[] args) {
        ReferenceQueue queue = new ReferenceQueue();
        List<byte[]> bytes = new ArrayList<>();
        PhantomReference<Worker> reference = new PhantomReference<Worker>(new Worker(),queue);
        new Thread(() -> {
            for (int i = 0; i < 100;i++ ) {
                bytes.add(new byte[1024 * 1024]);
            }
        }).start();

        new Thread(() -> {
            while (true) {
                // 发生GC的时候 会将 这个虚引用对象 reference 放到队列中
                // 如果这个对象是Cleaner的话，JVM还会触发Cleaner.clean方法，用于处理一些事情 比如jdk中的直接内存的空间释放
                Reference poll = queue.poll();
                if (poll != null) {
                    System.out.println("虚引用被回收了：" + poll);
                }
            }
        }).start();
        Scanner scanner = new Scanner(System.in);
        scanner.hasNext();
    }

}

